﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace CPPEI.Coolzon.UI
{
    /// <summary>
    /// 方案资源管理类
    /// </summary>
    public static class SolutionResourceManager
    {
        private static string s_solutionDirection;

        private static List<ImageSourceCacheItem> s_imageCache = new List<ImageSourceCacheItem>();

        private static object s_imageDictLockObj = new object();

        /// <summary>
        /// 初始化资源管理器
        /// </summary>
        /// <param name="soulutionDirection"></param>
        public static void Init(string soulutionDirection)
        {
            s_solutionDirection = soulutionDirection;
        }

        /// <summary>
        /// 获取静态数据文件的路径
        /// </summary>
        /// <param name="dataSource">数据源名称</param>
        /// <returns></returns>
        public static string GetStaticDataFilePath(string dataSource)
        {
            return string.Format("{0}\\$data\\{1}.dat", s_solutionDirection, dataSource);
        }

        /// <summary>
        /// 获取文件的绝对路径
        /// </summary>
        /// <param name="relativeFile"></param>
        /// <returns></returns>
        public static string GetAbsoluteFilePath(string relativeFile)
        {
            if (string.IsNullOrWhiteSpace(relativeFile))
            {
                return "";
            }
            if (relativeFile.StartsWith("./"))
            {
                return relativeFile.Replace("./", s_solutionDirection);
            }
            else if(relativeFile.StartsWith(".\\"))
            {
                return relativeFile.Replace(".\\", s_solutionDirection);
            }
            else if (relativeFile.StartsWith("."))
            {
                return System.IO.Path.Combine(s_solutionDirection, relativeFile);
            }
            if (System.IO.File.Exists(relativeFile))
            {
                return relativeFile;
            }
            return string.Format("{0}{1}", s_solutionDirection, relativeFile);
        }

        public static string GetRelativeFilePath(string absoluteFilePath)
        {
            return absoluteFilePath.Replace("/", "\\").Replace(s_solutionDirection.Replace("/", "\\"), ".\\");
        }

        private static BitmapImage GetBitmapImageFromCache(string key)
        {
            BitmapImage refBitmapImage = null;
            for (int index = 0; index < s_imageCache.Count; index++)
            {
                if (string.Equals(s_imageCache[index].Key, key))
                {
                    refBitmapImage = s_imageCache[index].BitmapImage.Target as BitmapImage;
                    if (refBitmapImage == null)
                    {
                        s_imageCache.RemoveAt(index);
                    }
                    break;
                }
            }
            return refBitmapImage;
        }

        /// <summary>
        /// 获取画刷
        /// </summary>
        /// <param name="relativeFile"></param>
        /// <returns></returns>
        public static BitmapImage GetImage(string relativeFile)
        {
            string absolutePath = GetAbsoluteFilePath(relativeFile);
            try
            {
                FileInfo file = new FileInfo(absolutePath);
                if (file != null && file.Exists)
                {
                    BitmapImage refBitmapImage = new BitmapImage();

                    //此种方式会占用文件
                    //refBitmapImage.BeginInit();
                    //refBitmapImage.UriSource = new Uri(absolutePath);
                    //refBitmapImage.EndInit();

                    using (FileStream fileStream = File.Open(file.FullName, FileMode.Open, FileAccess.Read))
                    {
                        using (BinaryReader binReader = new BinaryReader(fileStream))
                        {
                            byte[] bytes = binReader.ReadBytes((int)file.Length);

                            refBitmapImage = new BitmapImage();
                            refBitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                            refBitmapImage.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
                            refBitmapImage.BeginInit();
                            refBitmapImage.StreamSource = new MemoryStream(bytes);
                            refBitmapImage.EndInit();
                        }
                    }
                    return refBitmapImage;
                }
                else
                {
                    Common.Logger.ErrorToTag("UI", "加载Image:{0}失败,文件不存在", relativeFile);
                    return null;
                }
            }
            catch(Exception ex)
            {
                Common.Logger.ErrorToTag("UI", "加载Image:{0}失败,ex:{1}", relativeFile, ex);
                return null;
            }
        }

        /// <summary>
        /// 获取画刷
        /// </summary>
        /// <param name="relativeFile"></param>
        /// <returns></returns>
        public static BitmapImage GetImageNoCache(string relativeFile)
        {
            string absolutePath = GetAbsoluteFilePath(relativeFile);
            try
            { 
                FileInfo file = new FileInfo(absolutePath);
                if (file != null && file.Exists)
                {
                    BitmapImage bitmapImage = new BitmapImage(new Uri(file.FullName));//, new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore));
                    double oWidth = bitmapImage.Width;
                    double oHeight = bitmapImage.Height;
                    if (Settings.Instance.BigImageResouceQuality != 1.0d && oWidth > 255 && oHeight > 255)
                    {
                        bitmapImage = new BitmapImage();
                        bitmapImage.BeginInit();
                        bitmapImage.UriSource = new Uri(file.FullName);
                        bitmapImage.DecodePixelWidth = (int)(oWidth * Settings.Instance.BigImageResouceQuality);
                        bitmapImage.DecodePixelHeight = (int)(oHeight * Settings.Instance.BigImageResouceQuality);
                        bitmapImage.EndInit();
                        return bitmapImage;
                    }
                    else
                    {
                        return bitmapImage;
                    }
                }
                else
                {
                    Common.Logger.ErrorToTag("UI", "加载Image:{0}失败,文件不存在", relativeFile);
                    return null;
                }
            }
            catch (Exception ex)
            {
                Common.Logger.ErrorToTag("UI", "加载Image:{0}失败,ex:{1}", relativeFile, ex);
                return null;
            }
        }

        /// <summary>
        /// 清除所有的资源缓存
        /// </summary>
        public static void ClearAll()
        {
            for (int index = 0; index < s_imageCache.Count; index++)
            {
                BitmapImage bitmap = s_imageCache[index].BitmapImage.Target as BitmapImage;
                if (bitmap != null)
                {
                    if (bitmap.IsFrozen)
                    {
                        Common.Logger.WarningToTag("UI", "SolutionResourceManager 删除BitmapImage：{0}，index:{1},失败，对象IsFrozen", s_imageCache[index].Key, index);
                    }
                    else
                    {
                        try
                        {
                            bitmap.StreamSource.Close();

                            bitmap.StreamSource = null;
                            Common.Logger.InfoToTag("UI", "SolutionResourceManager 删除BitmapImage：{0}，index:{1}", s_imageCache[index].Key, index);
                        }
                        catch (Exception ex)
                        {
                            Common.Logger.ErrorToTag("UI", "SolutionResourceManager 删除BitmapImage：{0}，ex:{1}", s_imageCache[index].Key, ex);
                        }
                    }
                }
            }
            s_imageCache.Clear();
        }

        public static void RemoveNullImageCache()
        {
            lock (s_imageDictLockObj)
            {
                for (int index = 0; index < s_imageCache.Count; )
                {
                    if (s_imageCache[index].BitmapImage.Target == null)
                    {
                        GC.RemoveMemoryPressure(s_imageCache[index].StreamLength);
                        //s_imageCache[index].FileStream.Close();
                        s_imageCache.RemoveAt(index);
                    }
                    else
                    {
                        index++;
                    }
                }
            }
        }
    }

    class ImageSourceCacheItem
    {
        public long StreamLength { get; set; }
        public string Key { get; set; }
        public WeakReference BitmapImage { get; set; }
        //public Stream FileStream { get; set; }
    }
}
